/**
 * 
 */
package ro.dta.idbi.ui;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;

import ro.dta.idbi.interfaces.ApplicationSections;
import ro.dta.idbi.interfaces.IProject;
import ro.dta.idbi.interfaces.ui.IMainFrame;
import ro.dta.idbi.interfaces.ui.IProjectPane;
import ro.dta.idbi.model.Utils;
import ro.dta.idbi.ui.sql.FDTool;

/**
 * Main menu bar of the application
 * 
 * @author Tudor Dobrila
 */
class MainMenuBar extends JMenuBar implements ActionListener {

	private static final long serialVersionUID = 276959048041409355L;

	private final transient IMainFrame parentFrame;

	private final transient JMenuItem saveItem, saveAsItem;

	/**
	 * MainMenuBar class constructor
	 */
	public MainMenuBar(final IMainFrame parentFrame) {
		super();
		this.parentFrame = parentFrame;

		final JMenu fileItem = new JMenu("File");
		fileItem.setMnemonic(KeyEvent.VK_F);
		add(fileItem);

		final JMenuItem newProjItem = new JMenuItem("New Integration Project");
		newProjItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_I, ActionEvent.CTRL_MASK));
		newProjItem.getAccessibleContext().setAccessibleDescription(
				"Start a new database schema integration project");
		newProjItem.setName("newproj");
		newProjItem.addActionListener(this);
		newProjItem.setMnemonic(KeyEvent.VK_I);
		newProjItem.setIcon(new ImageIcon("./resources/integrate_small.png"));
		fileItem.add(newProjItem);

		final JMenuItem openProjItem = new JMenuItem("Open Project...");
		openProjItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.CTRL_MASK));
		openProjItem.getAccessibleContext()
				.setAccessibleDescription("Load a project from the disk");
		openProjItem.setName("open");
		openProjItem.addActionListener(this);
		openProjItem.setMnemonic(KeyEvent.VK_O);
		openProjItem.setIcon(new ImageIcon("./resources/open_small.png"));
		fileItem.add(openProjItem);

		fileItem.addSeparator();

		saveItem = new JMenuItem("Save");
		saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
		saveItem.getAccessibleContext()
				.setAccessibleDescription("Save project to default location");
		saveItem.setName("save");
		saveItem.addActionListener(this);
		saveItem.setMnemonic(KeyEvent.VK_S);
		saveItem.setIcon(new ImageIcon("./resources/save_small.png"));
		saveItem.setEnabled(false);
		fileItem.add(saveItem);

		saveAsItem = new JMenuItem("Save As...");
		saveAsItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK
				| ActionEvent.SHIFT_MASK));
		saveAsItem.getAccessibleContext().setAccessibleDescription(
				"Choose save path and save project");
		saveAsItem.setName("saveas");
		saveAsItem.addActionListener(this);
		saveAsItem.setIcon(new ImageIcon("./resources/saveas_small.png"));
		saveAsItem.setEnabled(false);
		fileItem.add(saveAsItem);

		fileItem.addSeparator();

		final JMenuItem configItem = new JMenuItem("AutoMed Configuration...");
		configItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, ActionEvent.CTRL_MASK));
		configItem.getAccessibleContext().setAccessibleDescription(
				"View / edit the AutoMed configuration file");
		configItem.setName("config");
		configItem.addActionListener(this);
		configItem.setMnemonic(KeyEvent.VK_C);
		fileItem.add(configItem);

		final JMenuItem exitItem = new JMenuItem("Exit");
		exitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4, ActionEvent.ALT_MASK));
		exitItem.getAccessibleContext().setAccessibleDescription("Close application");
		exitItem.setName("exit");
		exitItem.addActionListener(this);
		exitItem.setMnemonic(KeyEvent.VK_E);
		fileItem.add(exitItem);

		final JMenu repItem = new JMenu("Repository");
		repItem.getAccessibleContext().setAccessibleDescription("AutoMed repository options");
		add(repItem);

		final JMenuItem showSchItem = new JCheckBoxMenuItem("Show only end of pathway schemas");
		showSchItem.getAccessibleContext().setAccessibleDescription(
				"Show only end of pathway schemas");
		showSchItem.setMnemonic(KeyEvent.VK_P);
		showSchItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.CTRL_MASK));
		showSchItem.addActionListener(this);
		showSchItem.setName("schemadet");
		repItem.add(showSchItem);

		final JMenuItem showRepItem = new JCheckBoxMenuItem("Show / Hide Browser");
		showRepItem.getAccessibleContext().setAccessibleDescription("Show / hide the repository");
		showRepItem.setMnemonic(KeyEvent.VK_H);
		showRepItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_H, ActionEvent.CTRL_MASK));
		showRepItem.addActionListener(this);
		showRepItem.setName("showhide");
		showRepItem.setSelected(true);
		repItem.add(showRepItem);

		final JMenuItem addSrcItem = new JMenuItem("Add New Source");
		addSrcItem.getAccessibleContext().setAccessibleDescription(
				"Add a new source to the AutoMed repository");
		addSrcItem.setMnemonic(KeyEvent.VK_N);
		addSrcItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
		addSrcItem.addActionListener(this);
		addSrcItem.setName("addsrc");
		repItem.add(addSrcItem);

		final JMenuItem refreshItem = new JMenuItem("Refresh");
		refreshItem.getAccessibleContext().setAccessibleDescription(
				"Refresh the AutoMed repository browser");
		refreshItem.setMnemonic(KeyEvent.VK_R);
		refreshItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK));
		refreshItem.addActionListener(this);
		refreshItem.setName("refresh");
		repItem.add(refreshItem);
		
		final JMenu toolsItem = new JMenu("Tools");
		toolsItem.getAccessibleContext().setAccessibleDescription("Utility integration tools");
		add(toolsItem);

		final JMenuItem transHistItem = new JMenuItem("Transaction history browser");
		transHistItem.getAccessibleContext().setAccessibleDescription(
				"View the history of the transactions");
		transHistItem.addActionListener(this);
		transHistItem.setName("transhist");
		transHistItem.setIcon(new ImageIcon("./resources/history.png"));
		toolsItem.add(transHistItem);
		
		final JMenuItem dynPattItem = new JMenuItem("Pattern extractor / dependency viewer");
		dynPattItem.getAccessibleContext().setAccessibleDescription(
				"Dynamic pattern generator / depenency viewer");
		dynPattItem.addActionListener(this);
		dynPattItem.setName("dynpatt");
		toolsItem.add(dynPattItem);
		
		final JMenuItem schMatchItem = new JMenuItem("Schema matching tool");
		schMatchItem.getAccessibleContext().setAccessibleDescription(
				"Schema matching tool, used to automatically identify correspondences");
		schMatchItem.addActionListener(this);
		schMatchItem.setName("matchtool");
		toolsItem.add(schMatchItem);
		
		final JMenuItem fdToolItem = new JMenuItem("Functional dependency discovery");
		fdToolItem.getAccessibleContext().setAccessibleDescription(
				"Functional dependency discovery tool");
		fdToolItem.addActionListener(this);
		fdToolItem.setName("fdtool");
		toolsItem.add(fdToolItem);
	}

	/**
	 * Set if the save item in the menu bar is enabled
	 * 
	 * @param enabled
	 *            True if save item should be enabled, false otherwise
	 */
	public void setSaveEnabled(final boolean enabled) {
		saveItem.setEnabled(enabled);
	}

	/**
	 * Set if the save as item in the menu bar is enabled
	 * 
	 * @param enabled
	 *            True if save as item should be enabled, false otherwise
	 */
	public void setSaveAsEnabled(final boolean enabled) {
		saveAsItem.setEnabled(enabled);
	}

	@Override
	public void actionPerformed(final ActionEvent event) {
		final JMenuItem menuItem = (JMenuItem) event.getSource();

		if (menuItem.getName().equals("newproj")) {
			// New integration project
			parentFrame.open(ApplicationSections.PROJECT, new Object[] {}, "project"
					+ (MainFrame.projectCount++), new ImageIcon("./resources/integrate_icon.png"),
					"Pre-integration: Choose Schemas & Define Integration Strategy",
					"Add schemas and combine them to define the integration strategy.");
		} else if (menuItem.getName().equals("open")) {
			// Open project from disk
			final IProject project = UiUtils.loadProject(parentFrame, parentFrame.getRightPane());

			if (project != null) {
				final String name = (new File(project.getFileName())).getName();
				parentFrame.open(ApplicationSections.PROJECT, new Object[] { project }, name,
						new ImageIcon("./resources/integrate_icon.png"), "",
						"Add schemas and combine them to define the integration strategy.");
			}
		} else if (menuItem.getName().equals("save") || menuItem.getName().equals("saveas")) {
			// Save project to default location
			final Component tabComp = parentFrame.getRightPane().getSelectedComponent();

			if (tabComp instanceof RightPanel
					&& ((RightPanel) tabComp).getContent() instanceof IProjectPane) {
				final IProjectPane projPane = (IProjectPane) ((RightPanel) tabComp).getContent();
				final String path = projPane.getProject().getFileName();
				if ((menuItem.getName().equals("save") && (path == null || path.equals("")))
						|| menuItem.getName().equals("saveas")) {
					UiUtils.saveProject(parentFrame, (JComponent) tabComp, projPane.getProject());
				} else {
					try {
						projPane.getProject().save();
						parentFrame.setStatusBarText("Project successfully saved to " + path);
					} catch (Exception e1) {
						JOptionPane.showMessageDialog(tabComp,
								"Could not save project!\r\nReason: " + e1.getMessage(), "Error",
								JOptionPane.ERROR_MESSAGE);
					}
				}
			}
		} else if (menuItem.getName().equals("config")) {
			// View / edit the configuration file
			try {
				Utils.openConfiguration();
			} catch (IOException e1) {
				JOptionPane.showMessageDialog(this,
						"Could not open the AutoMed configuration file!", "Error",
						JOptionPane.ERROR_MESSAGE);
			}
		} else if (menuItem.getName().equals("exit")) {
			// Close application
			System.exit(0);
		} else if (menuItem.getName().equals("refresh")) {
			// Refresh repository browser
			parentFrame.getRepositoryBrowser().refresh();
			parentFrame.setStatusBarText("Repository browser has been refreshed.");
		} else if (menuItem.getName().equals("addsrc")) {
			// Add source to the repository
			final AddSourceDialog addSrcFrame = new AddSourceDialog(parentFrame);
			addSrcFrame.setVisible(true);
		} else if (menuItem.getName().equals("showhide")) {
			final JCheckBoxMenuItem checkItem = (JCheckBoxMenuItem) menuItem;
			parentFrame.showRepBrowser(checkItem.isSelected());
		} else if (menuItem.getName().equals("schemadet")) {
			// Show only end of pathways schemas
			final JCheckBoxMenuItem checkItem = (JCheckBoxMenuItem) menuItem;
			parentFrame.getRepositoryBrowser().showAllSchemas(!checkItem.isSelected());
		} else if (menuItem.getName().equals("dynpatt")) {
			DepGraphDialog dlg = new DepGraphDialog(parentFrame);
			dlg.setVisible(true);
		} else if (menuItem.getName().equals("fdtool")) {
			FDTool fdDlg = new FDTool(parentFrame);
			fdDlg.setVisible(true);
		} else if (menuItem.getName().equals("transhist")) {
			TransactionHistoryDialog thd = new TransactionHistoryDialog(parentFrame, (String)null);
			thd.setVisible(true);
		} else if (menuItem.getName().equals("matchtool")) {
			MatchingTool matchTool = new MatchingTool(parentFrame);
			matchTool.setVisible(true);
		}
	}
}
